package com.taoism.model;


import com.taoism.customEnum.ResultEnum;
import com.taoism.utils.CustomUtil;
import com.taoism.utils.DateUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

/**
 * 自定义消息返回体
 *
 * @author 李嘉
 * @version 1.0
 * @Description 自定义消息返回体
 * @date 2019/1/8 19:40
 */
@Builder
@ApiModel(value = "统一消息返回体", description = "统一带有泛型返回的消息体")
public class CustomResult<T> implements Serializable {

    private final static long serialVersionUID = -1L;

    /**
     * 结果Id
     */
    @Getter
    @ApiModelProperty(value = "返回结果Id")
    private final String resultId = CustomUtil.GenerateID();

    /**
     * 是否成功
     */
    @Getter
    @Setter
    @ApiModelProperty(value = "是否成功")
    private boolean success;

    /**
     * 代码编号
     */
    @Getter
    @Setter
    @ApiModelProperty(value = "状态码")
    private Integer code;

    /**
     * 数据集
     */
    @Getter
    @Setter
    @ApiModelProperty(value = "数据对象")
    private T data;

    /**
     * 消息
     */
    @Getter
    @Setter
    @ApiModelProperty(value = "消息")
    private String msg;

    /**
     * 数据大小
     */
    @Getter
    @Setter
    @ApiModelProperty(value = "数据大小")
    private long count;

    /**
     * 最后更新时间
     */
    @Getter
    @ApiModelProperty(value = "最后更新时间，指当前数据查询的时间")
    private final String lastTime = DateUtil.GetFormatTime();

    /**
     * 无参数构造函数
     */
    public CustomResult() {

    }

    /**
     * 有参数构造函数
     * @param success   是否成功
     * @param code      编码
     * @param data      数据对象集
     * @param message   消息
     * @param count     总数
     */
    public CustomResult(boolean success, Integer code, T data, String message, long count) {
        this.success = success;
        this.code = code;
        this.data = data;
        this.msg = message;
        this.count = count;
    }

    /**
     * 自定义生成结果对象
     *
     * @param success
     * @param code
     * @return
     */
    public static <T> CustomResult<T> build(boolean success, Integer code) {
        return CustomResult.<T>builder()
                .success(success)
                .code(code)
                .build();
    }

    /**
     * 自定义生成结果对象
     *
     * @param success
     * @param code
     * @param data
     * @return
     */
    public static <T> CustomResult<T> build(boolean success, Integer code, T data) {
        return CustomResult.<T>builder()
                .success(success)
                .code(code)
                .data(data)
                .build();
    }

    /**
     * 自定义生成结果对象
     *
     * @param success
     * @param code
     * @param data
     * @param count
     * @return
     */
    public static <T> CustomResult<T> build(boolean success, Integer code, T data, long count) {
        return CustomResult.<T>builder()
                .success(success)
                .code(code)
                .data(data)
                .count(count)
                .build();
    }

    /**
     * 自定义生成结果对象
     *
     * @param success
     * @param code
     * @param message
     * @return
     */
    public static <T> CustomResult<T> build(boolean success, Integer code, String message) {
        return CustomResult.<T>builder()
                .success(success)
                .code(code)
                .msg(message)
                .build();
    }

    /**
     * 自定义生成结果对象
     *
     * @param success
     * @param code
     * @param data
     * @param message
     * @return
     */
    public static <T> CustomResult<T> build(boolean success, Integer code, T data, String message) {
        return CustomResult.<T>builder()
                .success(success)
                .code(code)
                .data(data)
                .msg(message)
                .build();
    }

    /**
     * 自定义生成结果对象
     *
     * @param success
     * @param code
     * @param data
     * @param message
     * @param count
     * @return
     */
    public static <T> CustomResult<T> build(boolean success, Integer code, T data, String message, long count) {
        return CustomResult.<T>builder()
                .success(success)
                .code(code)
                .data(data)
                .msg(message)
                .count(0)
                .build();
    }

    /**
     * 成功
     *
     * @return
     */
    public static <T> CustomResult<T> ok() {
        return CustomResult.<T>builder()
                .success(true)
                .code(ResultEnum.Success.getIndex())
                .count(0)
                .build();
    }

    /**
     * 成功
     *
     * @param data
     * @return
     */
    public static <T> CustomResult<T> ok(T data) {
        return CustomResult.<T>builder()
                .success(true)
                .code(ResultEnum.Success.getIndex())
                .data(data)
                .count(0)
                .build();
    }

    /**
     * 成功
     *
     * @param code
     * @param data
     * @return
     */
    public static <T> CustomResult<T> ok(Integer code, T data) {
        return CustomResult.<T>builder()
                .success(true)
                .code(code)
                .data(data)
                .count(0)
                .build();
    }

    /**
     * 成功
     *
     * @param data
     * @param count
     * @return
     */
    public static <T> CustomResult<T> ok(T data, long count) {
        return CustomResult.<T>builder()
                .success(true)
                .code(ResultEnum.Success.getIndex())
                .data(data)
                .count(count)
                .build();
    }

    /**
     * 成功
     *
     * @param code
     * @param data
     * @param count
     * @return
     */
    public static <T> CustomResult<T> ok(Integer code, T data, long count) {
        return CustomResult.<T>builder()
                .success(true)
                .code(code)
                .data(data)
                .count(count)
                .build();
    }

    /**
     * 失败
     *
     * @param message
     * @return
     */
    public static <T> CustomResult<T> fail(String message) {
        return CustomResult.<T>builder()
                .success(false)
                .code(ResultEnum.Fail.getIndex())
                .msg(message)
                .count(0)
                .build();
    }

    /**
     * 失败
     *
     * @param code
     * @param message
     * @return
     */
    public static <T> CustomResult<T> fail(Integer code, String message) {
        return CustomResult.<T>builder()
                .success(false)
                .code(code)
                .msg(message)
                .count(0)
                .build();
    }
}
